Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate trio.ssl from star import to explicit imports, to aid static analysis issue #542 #752

Merged
merged 18 commits into from
Dec 13, 2018

Conversation

jmfrank63
Copy link
Contributor

Use less magic in constructing our public API exports, to make trio more intelligible to static analysis #542

@jmfrank63
Copy link
Contributor Author

One test is failing but I cannot see where the import gets overwritten again.

____________________________________________ test_module_metadata_is_fixed_up ____________________________________________

    def test_module_metadata_is_fixed_up():
        import trio
        assert trio.Cancelled.__module__ == "trio"
        assert trio.open_cancel_scope.__module__ == "trio"
>       assert trio.ssl.SSLStream.__module__ == "trio.ssl"
E       AssertionError: assert 'ssl' == 'trio.ssl'
E         - ssl
E         + trio.ssl

trio/tests/test_util.py:73: AssertionError

Any ideas are welcome.

@codecov
Copy link

codecov bot commented Oct 28, 2018

Codecov Report

Merging #752 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #752      +/-   ##
==========================================
+ Coverage   99.01%   99.01%   +<.01%     
==========================================
  Files          96       96              
  Lines       11673    11677       +4     
  Branches      832      830       -2     
==========================================
+ Hits        11558    11562       +4     
  Misses         94       94              
  Partials       21       21
Impacted Files Coverage Δ
trio/tests/test_exports.py 96.36% <ø> (-0.07%) ⬇️
trio/_ssl.py 98.93% <ø> (-0.07%) ⬇️
trio/tests/test_ssl.py 97.75% <100%> (ø) ⬆️
trio/ssl.py 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6bc3b0b...774e1e8. Read the comment docs.

trio/ssl.py Outdated Show resolved Hide resolved
get_default_verify_paths, Purpose, enum_certificates, enum_crls,
SSLSession, VerifyMode, VerifyFlags, Options, AlertDescription,
SSLErrorNumber
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These don't need to be fake! It's a well-defined set of things that should always be available. So we can just do a regular old import without any try/except.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some actually don't but others do. I tried to import them directly but the test failed on some versions of python and with windows. I decided to revert back to being them all fake since doing a subset one way and the rest the other is more confusing and IMHO not worth the extra lines of code. Is this fine with you?

"VerifyFlags", "Options", "AlertDescription", "SSLErrorNumber"
]
}
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we switch to a regular import above, we can delete this.


for _name in _stdlib_ssl.__dict__.keys():
if _name == _name.upper():
_reexport(_name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is like trio.socket: it re-exports all the uppercased symbols. So we need some similar handling: a fake try/import, plus moving this loop into trio/ssl.py. With this PR right now it looks like we aren't re-exporting the uppercased symbols at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ups, I overlooked this totally, yes of course, this has to be addressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are now imported, but see my comment below about external dependencies like ssl library and version.

@njsmith
Copy link
Member

njsmith commented Oct 29, 2018

It might make sense to merge #756 before this, and then use #756's new tests instead of adding tests here.

@njsmith
Copy link
Member

njsmith commented Nov 5, 2018

This also needs a merge from master to pick up the changes in #756. Plus addressing the other comments above, of course :-)

@jmfrank63
Copy link
Contributor Author

This also needs a merge from master to pick up the changes in #756. Plus addressing the other comments above, of course :-)

Right, I did this for #753 but totally forgot about this one. I'll also remove the extra imports. Might take a couple of days, I am really busy right now.

@njsmith
Copy link
Member

njsmith commented Nov 5, 2018

No worries 👍

@jmfrank63
Copy link
Contributor Author

That's strange. I expected the test to fail, as I am only importing the ssl Mac symbols, so the jedi and pylint test for windows and linux should show some missing symbols. I'll checkout this repo on windows and see if it passes locally as well check which symbols are imported.
I also tried to import directly but only a subset of symbols was available on each system which made the tests to fail. Therefore I moved back to the try catch block which seems fine now.
@njsmith Let me know what you think.

@jmfrank63
Copy link
Contributor Author

I can confirm the tests did not catchOP_NO_RENEGOTIATION of the ssl module missing on windows. I assume this should be another issue, I'll try to get the missing symbols on linux via wsl.

@njsmith
Copy link
Member

njsmith commented Nov 10, 2018

I think that the main thing that determines which symbols appear on a given Python is (a) which version of Python you're using, and (b) which version of OpenSSL this Python was built against. I don't think it varies across platforms, except that if you grab a random Windows build and a random MacOS build then they may well have been built against different versions of OpenSSL.

@jmfrank63
Copy link
Contributor Author

I think that the main thing that determines which symbols appear on a given Python is (a) which version of Python you're using, and (b) which version of OpenSSL this Python was built against. I don't think it varies across platforms, except that if you grab a random Windows build and a random MacOS build then they may well have been built against different versions of OpenSSL.

Understood, but that does not make it especially easier. Python can not only be build against different versions of OpenSSL it can also be build against other SSL libraries, e.g. LibreSSL.
Building tests for these scenarios will IMHO be not worth the effort.

@njsmith
Copy link
Member

njsmith commented Nov 24, 2018

  1. It looks like this PR isn't actually enabling the generic exports test for the trio.ssl module? You need to remove this line from trio/test/test_exports.py:
NAMESPACES.remove("trio.ssl")
  1. I see what you mean about the different versions being frustrating... but I'm still wincing a lot at the duplicate lists :-(. As one last try before we give up and maintain two lists of symbols, can we try the following?
# Always available
from ssl import (
     cert_time_to_seconds, CertificateError,
     create_default_context, DER_cert_to_PEM_cert,
     get_default_verify_paths, match_hostname,
     PEM_cert_to_DER_cert, Purpose, SSLEOFError, SSLError, 
     SSLSyscallError, SSLZeroReturnError
) 

# Added in python 3.6
try:
    from ssl import AlertDescription, SSLErrorNumber, SSLSession, VerifyFlags, VerifyMode, Options
except ImportError:
    pass

# Added in python 3.7
try:
    from ssl import SSLCertVerificationError, TLSVersion
except ImportError:
    pass

# Windows-only
try:
    from ssl import enum_certificates, enum_crls
except ImportError:
    pass

(It looks like the constants available depend on openssl version, but these lowercase things are mostly dependent on Python version.)

@jmfrank63
Copy link
Contributor Author

@njsmith Hi Nathaniel, thanks for the feedback and sorry for the delayed answer. I was really busy over the past days. I'll try to implement what you suggest and notify you once done. Thank you so much for letting me taking part of this awesome project.

@jmfrank63
Copy link
Contributor Author

??? I thought the second last test failed for pypy but now it is actually telling me that this test succeeded?
Well the difference is just two blocks vs one but the browser behaviour sometimes is really weird.
The split of blocks can easily be fixed by a rollback though. @njsmith Could you take a look?

@jmfrank63 jmfrank63 changed the title migrated trio.ssl from star import to explicit imports, to aid static analysis migrated trio.ssl from star import to explicit imports, to aid static analysis issue #542 Dec 9, 2018
@jmfrank63 jmfrank63 changed the title migrated trio.ssl from star import to explicit imports, to aid static analysis issue #542 migrate trio.ssl from star import to explicit imports, to aid static analysis issue #542 Dec 9, 2018
@njsmith
Copy link
Member

njsmith commented Dec 12, 2018

This is looking good, except for some dead code left behind... let me try deleting that and check if it still works.

@njsmith njsmith merged commit 9799564 into python-trio:master Dec 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants